package com.zxl.study.config;

import com.github.benmanes.caffeine.cache.Cache;
import io.lettuce.core.RedisClient;
import io.lettuce.core.TrackingArgs;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.codec.StringCodec;
import io.lettuce.core.support.caching.CacheFrontend;
import io.lettuce.core.support.caching.ClientSideCaching;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @auther zxl
 * @create 2024-01-24 17:50
 * localCacheCaffeine
 */
@Slf4j
@NoArgsConstructor
public class CacheManager {
    //cacheFrontend会自动处理本地缓存和 Redis 缓存的交互
    @Getter
    private CacheFrontend cacheFrontend;

    private RedisClient redisClient;
    private Cache localCacheCaffeine;

    StatefulRedisConnection<String, String> connection;

    public CacheManager(RedisClient redisClient, Cache localCacheCaffeine) {
        this.redisClient = redisClient;
        this.localCacheCaffeine = localCacheCaffeine;
    }

    public void check() {
        if (connection != null) {
            if (connection.isOpen()) {
                System.out.println("-------redis 链接都正常");
                return;
            }
        }

        try {
            connection = redisClient.connect();
            cacheFrontend = ClientSideCaching.enable(new CaffeineCacheAccessor(localCacheCaffeine), connection,
                    TrackingArgs.Builder.enabled());
            //connection.addListener 方法用于监听 Redis 的键事件
            connection.addListener(message -> {
                List<Object> content = message.getContent(StringCodec.UTF8::decodeKey);
                log.info("-----监听到远程redis有变化，属性type:{},connect:{}", message.getType(), content);
                switch (message.getType().toLowerCase()) {
                    case "del":
                    case "expired":
                    case "evicted":
                    case "invalidate":
                        List<String> keys = (List<String>) content.get(1);
                        keys.forEach(key -> localCacheCaffeine.invalidate(key));
                        log.info("本地缓存失效，keys: {}", keys);
                        break;
                    default:
                        log.warn("未知的事件类型: {}", message.getType());
                        break;
                }
            });
            log.warn("The redis client connect is success且监听器connection.addListener有效");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("The redis client disconnected,bad luck+Fuck," +
                    "reconnecting...please wait a moment" + "\t" + e.getMessage());
        }
    }
}
